11장. 결합 재조정

출처: 『소프트웨어 설계의 결합 균형』(블라드 코노노프 지음, 장연호 옮김, 제이펍 2026) | 공식: https://www.jpub.kr/

시스템은 변하고, 뒤틀리고, 소리치고, 계획된 경로에서 때때로 벗어난다. 재조정(rebalancing)은 예외가 아니라 일상이다 — 결합 균형이 깨졌을 때 어느 차원(강도·거리·변동성)을 어떻게 조정할지를 아는 것이 이 장의 핵심이다.

학습 목표

이 장을 끝내면 다음을 할 수 있다.

  • 소프트웨어 변경을 전술적 변경전략적 변경으로 구분하고, 왜 전략적 변경이 결합 균형을 깨뜨리는지 설명한다.
  • 결합 균형 공식 BALANCE = (STRENGTH XOR DISTANCE) OR NOT VOLATILITY에서 세 차원이 어떻게 서로 보상하는지 분석한다.
  • 통합 강도·거리·변동성이 각각 변할 때 어떤 재조정 기법을 써야 하는지 판단한다.
  • WolfDesk 사례 연구를 통해 기능 추가·비즈니스 전략 전환·조직 변화가 결합에 미치는 영향을 추적한다.
  • 복잡성이 지역(local) ↔ 전역(global) 사이를 이동하는 트레이드오프를 설명한다.

전체 흐름도

[ 시스템에 변화가 온다 ]
        │
        ▼
[ 변화 유형 분류 ]
  전술적: "어떻게"를 바꿈 ──────────────────────────────▶ 현재 설계로 수용 가능
  전략적: "무엇을"을 바꿈 → 기존 가정이 깨짐
        │
        ▼
[ 결합 균형 점검 ]
  BALANCE = (STRENGTH XOR DISTANCE) OR NOT VOLATILITY
  ┌──────────────────────┬─────────────────────────────────────────┐
  │ 변한 차원             │ 보상 방법                               │
  ├──────────────────────┼─────────────────────────────────────────┤
  │ 강도(STRENGTH)↑      │ 거리를 줄인다 (기능 추출·이동)          │
  │ 변동성(VOLATILITY)↑  │ 강도를 낮추거나 거리를 줄인다           │
  │ 거리(DISTANCE)↑      │ 경계를 조인다 (모델→계약 결합 격상)     │
  └──────────────────────┴─────────────────────────────────────────┘
        │
        ▼
[ 재조정 기법 적용 ]
  - 기능 추출·이동 (Extract & Move)
  - 경계 강화 (API·계약 결합 도입)
  - 복제 유지 (변동성이 낮을 때만)
        │
        ▼
[ 결과 검증 ]
  지역 복잡성 ↔ 전역 복잡성 트레이드오프 확인
  → 이동해도 복잡성 총량이 줄어야 의미 있음

0. 사전 필수 용어

  • 결합 균형 공식BALANCE = (STRENGTH XOR DISTANCE) OR NOT VOLATILITY. 세 차원 중 하나가 바뀌면 다른 차원으로 보상해야 균형이 유지된다.
  • 전술적 변경 (Tactical Change) — "어떻게"를 바꾼다. 기존 설계·비즈니스 가정을 유지하면서 구현 방식을 개선. 현재 설계가 수용할 수 있다.
  • 전략적 변경 (Strategic Change) — "무엇을"을 바꾼다. 비즈니스 목표·도메인 자체가 재정의된다. 기존 설계 가정이 깨진다.
  • 통합 강도 (Integration Strength) — 두 구성요소가 얼마나 긴밀하게 협력하는가 (계약→기능→침입 결합 방향으로 강해짐).
  • 거리 (Distance) — 두 구성요소의 물리적·조직적 거리. 모놀리스 내 모듈은 가깝고, 별도 마이크로서비스는 멀다.
  • 변동성 (Volatility) — 구성요소가 얼마나 자주 바뀔 가능성이 있는가. 핵심 하위 도메인은 높고, 일반 하위 도메인은 낮다.
  • 핵심/지원/일반 하위 도메인 — 핵심(core): 경쟁 우위, 변동성 높음. 지원(supporting): 필요하지만 경쟁 우위 없음. 일반(generic): 범용 솔루션, 변동성 낮음.
  • 경쟁 조건 (Race Condition) — 비동기 통합에서 이벤트 전파 지연으로 상태 불일치가 발생하는 상황.
  • 지역 복잡성 (Local Complexity) — 단일 컴포넌트 안의 복잡성. 서비스 분리 시 감소하는 경향.
  • 전역 복잡성 (Global Complexity) — 컴포넌트 간 상호작용에서 발생하는 복잡성. 서비스 분리 시 증가하는 경향.

1. 왜 결합은 반드시 재조정이 필요한가

비유 — 도시 계획과 인구 변동

도시를 처음 설계할 때 학교 10개, 도로 4차선으로 기획했다. 10년 후 인구가 3배로 늘었다. 이제 4차선은 만성 정체, 학교는 콩나물시루가 됐다. "처음 설계가 잘못됐다"고 탓할 수 있을까? 아니다 — 그 당시엔 최선이었다. 하지만 지금의 도시를 위해선 재조정이 필요하다. 도로를 넓히거나(강도 줄임), 위성 도시를 만들거나(거리 조정), 학교를 더 짓거나(기능 추출).

소프트웨어도 똑같다. 이상적인 소프트웨어는 최초 릴리스로 모든 미래를 충족한다 — 하지만 그런 세상은 존재하지 않는다. 소프트웨어 시스템은 살아 있는 유기체처럼 변화하는 환경에서 생존하기 위해 진화해야 한다. 변화가 없다는 것은 노후화되고 있다는 신호다.

비유 — 옷장 계절 교체

봄에 맞게 정리한 옷장이 겨울이 오면 쓸모없어진다. 매 시즌 옷장을 재구성(재조정)하지 않으면 원하는 옷을 찾는 데 시간이 너무 오래 걸린다. 소프트웨어의 결합 재조정은 옷장 계절 교체와 같다 — 과거의 정리 방식을 부정하는 것이 아니라, 지금의 필요에 맞게 다시 정리하는 것이다.

핵심 원리: 예상치 못한 변화가 발생하면, 이전 설계 결정의 무결성을 의심하기보다 새로운 정보를 활용해 결합을 재조정하는 것이 설계 탄력성을 강화한다.

2. 소프트웨어 변경 벡터 — 전술적 vs 전략적

2.1 전술적 변경 — "어떻게"를 바꾼다

기존 설계·비즈니스 가정을 유지한 채 구현 방식을 개선한다. 전술적 변경은 예상할 수 있는 변화다. 적절한 소프트웨어 설계는 전술적 변경을 수용할 수 있어야 한다.

예시: - 버그 수정, 성능 개선 (논리적 문제 해결, 좀 더 효율적인 방법 적용) - 전자상거래에 새 결제 수단 추가 - 사용자 기본 설정 옵션 구현 - 기존 시스템에 새 보고 기능 통합

핵심: 구성요소 경계상호 관계를 바꾸지 않는다. 기존 비즈니스 규칙·가정을 준수하면서 현재 비즈니스 요구사항과 일치하는 새로운 기능을 도입한다.

잘못된 예: 전술적 변경을 전략적 변경으로 착각
──────────────────────────────────────────────
"단순히 if 문 몇 개 추가"라고 생각했는데
실은 비즈니스 도메인 모델 자체가 바뀐 경우.
→ 빙산의 일각: 표면엔 작은 if, 수면 아래엔 설계 전체를 뒤흔드는 가정 붕괴.
→ 무해해 보이는 에지 케이스 처리가 사실 비즈니스 도메인 모델의 상당한 변화를 요구하는 것.

올바른 예: 전술적 변경으로 실제 처리
──────────────────────────────────────────────
새 결제 수단 추가 → PaymentGateway 인터페이스에 새 구현체만 추가.
기존 경계·호출 코드 변경 없음.

2.2 전략적 변경 — "무엇을"을 바꾼다

전략적 변경은 실질적이다. '무엇'을 바꾼다 — 무엇이 구현되고 있는지, 시스템이 어떤 문제를 해결하는지, 어떤 조직/구조가 그것을 실행하는지. 구성요소의 관계를 불균형하게 만들어 모듈식 설계를 쓸모없게 만들 수 있다.

기능적 요구사항: 새로운 기능은 지식을 추가한다. 새로운 구성요소를 사용하면 구성요소 간 상호작용도 확장된다. 특정 지점에서 이러한 추가 상호작용은 인지 부하를 크게 증가시키고 결국 시스템의 복잡성을 부풀릴 가능성이 있다.

비즈니스 전략 변화: 하위 도메인 유형이 바뀐다.

[ 하위 도메인 유형 전환 예시 ]

일반 → 핵심:  오픈소스 CMS로 지식 기반 관리
                → 인하우스 맞춤 Knowledge Base로 전환 결정
                (변동성: 낮음 → 높음)

지원 → 핵심:  간단한 우선순위 로직을 두 컴포넌트에 복제
                → 우선순위 최적화가 핵심 경쟁력으로 격상
                (변동성: 낮음 → 높음)

핵심 → 일반:  시장에서 동일 솔루션이 SaaS로 나옴
                → 자체 개발 불필요, 외부 서비스로 대체
                (변동성: 높음 → 낮음)

일상 비유 — 노키아는 원래 고무 제조회사였다. 핵심 하위 도메인이 통신 하드웨어로 전환됐다. 기존 고무 공장 설계를 휴대폰 공장에 그대로 쓸 수 없는 것처럼, 도메인이 바뀌면 소프트웨어 설계도 바뀌어야 한다.

조직적 변화: 팀이 분리되거나 합쳐질 때 거리(distance)가 달라진다. 성장하는 조직에서 초기에 효과적이었던 커뮤니케이션·협업 패턴은 중소 규모 조직에 효과가 없는 경우가 많다.

[ 거리 변화 사례 ]

모놀리스 시절: Support Case Management + Distribution + Help Desks
                같은 코드베이스, 모두 가까운 거리
                → 인터페이스 조정이 쉽고 빠름 (리팩터링 비교적 용이)

팀 분리 후:    각 서비스가 다른 팀 소유, 다른 서비스로 분리
                → 거리 증가 → 수명 결합 감소 → 연쇄 변경 비용 증가
                → 경계를 "조여야" 함 (모델 결합 → 계약 결합으로 격상)

일상 비유 — 같은 사무실에 앉은 팀원끼리는 "야, 이 부분 API 좀 바꿔도 돼?"가 1분이면 해결된다. 다른 시간대 다른 도시로 팀이 쪼개지면 같은 협의에 이메일·회의·문서가 필요하다. 거리가 늘면 인터페이스를 더 엄격하게 정의해야 한다.

환경적 변화: 클라우드 이전(온프레미스→클라우드 "리프트 앤 시프트"는 종종 제한적 성공), 규제 변화(GDPR, HIPAA, SOX 등)는 시스템 구조 자체를 강제로 바꾼다.

3. 결합 재조정 기법

균형 공식 복습: BALANCE = (STRENGTH XOR DISTANCE) OR NOT VOLATILITY

한 차원이 바뀌면 다른 차원으로 보상해야 균형이 회복된다.

3.1 통합 강도 변화 → 거리로 보상

사례 — WolfDesk: 숨겨진 통합 강도

처음 설계: Help Desks가 일정 변경 이벤트를 메시지 버스에 게시 → Distribution이 구독하여 에이전트에게 근무 시간 동안만 새로운 지원 사례를 할당.

새 요구사항: 에이전트가 "할당 일시 중지" 버튼 클릭 → 즉시 효과 기대. 에이전트는 하루 최대 3번, 1시간씩 할당 일시 중지 가능.

즉시라는 기대는 사실상 트랜잭션 결합 수준의 높은 통합 강도다. 하지만 두 서비스는 여전히 비동기 이벤트 방식으로 통합 → 경쟁 조건(race condition) 발생. 버튼을 눌렀는데 이벤트가 아직 전파 안 된 사이에 새 사례가 할당된다.

Distribution 로직은 WolfDesk의 핵심 하위 도메인(높은 변동성) 중 하나이므로 높은 통합 강도를 균형 잡기 위해 거리를 줄여야 했다.

[ 문제 상태 ]
Help Desks ──(비동기 이벤트)──▶ Distribution
강도↑(트랜잭션 수준 기대) + 거리↑(비동기) = 불균형

[ 검토된 대안들 ]

대안 A: REST API로 일정 노출
  → 동기 쿼리로 데이터 신선도 개선
  → 하지만 API 응답과 할당 사이에 여전히 타이밍 문제
  → 오히려 런타임 결합 증가 (Help Desks 불가 → Distribution 불가)

대안 B: 두 서비스 병합
  → 데이터 일관성 해결
  → 하지만 관련 없는 기능들이 한 서비스에 → 지역 복잡성 증가

[ 선택한 해결책 ]
"할당 일시 중지" 기능을 Distribution 마이크로서비스 자체로 추출·이동

Help Desks ──(이벤트)──▶ Distribution ◀── [일시 중지: Distribution 내부]
→ 높은 통합 강도 + 높은 변동성을 거리 최소화로 균형
→ Distribution 로직에 사용 가능한 정보가 강한 일관성 보장

일상 비유 — 팀장이 다른 팀에 "이 업무 바로 처리해 주세요"라고 이메일 보내면 "당장"이 안 된다. 해결책은 그 업무를 내 팀 안으로 가져오는 것 (기능 추출·이동). 긴밀하게 협력해야 하는 일은 가까이 둔다.

사례 — WolfDesk: 통합 강도 없음에서 기능 결합으로 (변동성이 낮을 때 복제 허용)

Distribution 서비스가 피크 시간에 우선순위 로직을 추가 → 시간이 지나면서 RealTime Analytics에서도 동일 로직이 필요. 두 구성요소가 직접 통합되지 않았기 때문에 팀은 동일 로직을 RealTime Analytics에 복제.

결과: 이전에 어떤 식으로도 서로 통합되지 않았던 구성요소가 기능적으로 결합됨. 거리도 멀어 전역 복잡성 증가.

하지만 — 복제된 로직이 비교적 간단하고 변경될 것으로 예상되지 않았기 때문에 팀은 그대로 두기로 결정. 낮은 변동성은 높은 강도와 거리를 균형 있게 조정한다.

3.2 변동성 변화 → 강도 또는 거리로 보상

사례 — WolfDesk: 지원에서 핵심으로

처음: 중요도 평가 로직이 단순하고 변경 불필요 → Distribution과 RealTime Analytics 두 곳에 복제. 낮은 변동성이 높은 강도·먼 거리를 균형잡음.

변화: 우선순위 최적화가 핵심 경쟁력으로 격상. 변동성이 높아짐. 두 곳에 복제된 로직을 동기화해야 하는 부담이 폭발.

[ 문제 상태 ]
Distribution    ─── [중요도 평가 로직 복제] ─── RealTime Analytics
변동성↑ + 거리↑ + 강도↑ = 불균형

[ 해결책 ]
중복된 기능을 Support Case Management 서비스로 이동 (거리 제거)
→ 단일 소스 → 동기화 부담 제거

Support Case Management
    ├── 중요도 평가 로직 (단일 소스)
    ├── Distribution이 참조
    └── RealTime Analytics가 참조

사례 — WolfDesk: 일반에서 핵심으로

처음: 오픈소스 CMS가 지식 기반 관리. 낮은 변동성 → Support Case Management가 CMS DB에 직접 접근(침입 결합). 허용 가능했던 이유: 일반 하위 도메인, 변동성 낮음.

변화: 인하우스 Knowledge Base 개발 결정 → 핵심 하위 도메인으로 격상 → 변동성 급증.

[ 변화 전 ]
Support Case Management ──(직접 DB 접근)──▶ CMS DB
침입 결합 + 낮은 변동성 → 받아들일 만함

[ 변화 후 문제 ]
Knowledge Base가 자주 바뀔 예정 (핵심 하위 도메인)
침입 결합 + 높은 변동성 + 먼 거리 = 심각한 불균형

[ 해결책 ]
Knowledge Base 서비스에 API(계약 결합) 도입
→ 경계 강화, 직접 DB 접근 금지
→ 강도를 침입 결합 → 계약 결합으로 낮춤

일상 비유 — 동네 구멍가게가 단골 도매상 창고에 직접 들어가서 물건을 꺼내왔다(침입 결합). 변동성이 낮을 때는 묵인됐다. 그런데 그 도매상이 급성장해 창고가 매일 재배치된다면? 이제는 공식 주문서(API)를 통해서만 거래해야 한다 — 서로 경계를 지켜야 빠른 성장을 방해받지 않는다.

3.3 거리 변화 → 경계 강화로 대응

모놀리스에서 마이크로서비스로 분리 시: 거리가 늘어난다.

대응 전략: 모듈 경계에서 공유 지식을 줄인다. 구체적으로 모델 결합 → 계약 결합으로 통합 강도를 낮춘다.

[ 모놀리스 시절 — 가까운 거리 ]
Support Case Management ←→ Distribution
내부 모델 직접 공유 (모델 결합)
→ 빠른 수정 가능, 리팩터링 쉬움

[ 마이크로서비스 분리 후 — 먼 거리 ]
Support Case Management  ↔  Distribution
(다른 서비스, 다른 팀)
→ 모델 결합 유지 시: 한쪽 변경이 다른 쪽 깨뜨림
→ 해결: 계약(Contract) 기반 API로 경계 조임
         공유 지식 최소화 → 연쇄 변경 방지

일상 비유 — 같은 집에 사는 가족은 "냉장고 어디 있어?"를 큰소리로 묻고 바로 해결한다(가까운 거리, 느슨한 규칙). 다른 도시로 독립한 자녀에게는 정해진 약속(계약) 으로 소통한다 — "매주 일요일 저녁 7시에 전화". 거리가 멀수록 인터페이스가 명확해야 한다.

3.4 복잡성 재조정의 한계

재조정이 항상 복잡성을 줄이는 것은 아니다. 때로는 지역 복잡성을 전역 복잡성으로 이동시킬 뿐이다. 모든 성장을 결합의 힘을 재조정함으로써 관리할 수 있는 것은 아니다.

[ 트레이드오프 예시 ]

서비스 분리 전:  모놀리스 안 한 모듈이 복잡 (지역 복잡성 높음)
서비스 분리 후:  모듈들이 각자 서비스 → 모듈 자체는 단순
                  하지만 서비스 간 통신·계약·관측 복잡성 증가 (전역 복잡성 이동)

결론: 복잡성 총량이 줄지 않으면 재조정은 위치만 바꾼 것.
      다음 장(12장)에서 시스템 성장·진화 본질을 더 깊이 다룸.

4. 흔한 안티패턴

안티패턴 1 — 한 번에 다 재조정

잘못된 예: "결합이 엉망이니 모놀리스 전체를 마이크로서비스로 한 번에 분리하자."

위험: 거리가 갑자기 증가 → 수많은 경계 정의 필요
      경계가 잘못 나뉘면 전역 복잡성 폭발
      "Big Bang" 리팩토링 → 수개월 멈춤 → 비즈니스 가치 전달 중단

올바른 예: 불균형이 발생한 구성요소를 하나씩 식별하고 점진적으로 재조정한다. 각 재조정 후 균형 공식으로 검증.

일상 비유 — 어수선한 방을 한 번에 다 청소하려다 지쳐 포기하는 것 vs 매일 30분씩 한 구역씩 정리하는 것. 후자가 지속 가능하다.

안티패턴 2 — 재조정 미루기

잘못된 예: "지금은 바쁘니까 나중에 리팩토링하자"를 반복한다.

결과: 불균형이 쌓임 → 기술 부채 누적
      단순한 if 문이 쌓여 사실상 비즈니스 도메인 모델이 바뀐 것을 감추게 됨
      나중엔 어디서부터 손대야 할지 모르는 상황

올바른 예: 전략적 변경이 감지되는 순간 결합 균형 공식으로 진단 → 불균형 파악 → 작은 재조정부터 시작.

일상 비유 — 팀 자리 재배치를 미루면 어느 날 갑자기 30명이 한꺼번에 이사해야 하는 상황이 온다. 성장에 맞춰 조금씩 자리를 바꾸는 게 훨씬 낫다.

5. 코드 리팩토링 기법 — 재조정 도구

기법 1 — 기능 추출·이동 (Extract & Move)

통합 강도가 높아진 기능을 별도 컴포넌트로 분리하거나 더 가까운 컴포넌트로 이동.

# 잘못된 예: 할당 일시 중지 로직이 Help Desks에 있고 Distribution이 이벤트로 받음
class HelpDesksService:
    def pause_assignment(self, agent_id, duration_hours):
        # 이벤트 게시 → Distribution에서 비동기 처리
        self.event_bus.publish("AssignmentPaused", {
            "agent_id": agent_id,
            "duration": duration_hours
        })
        # 문제: 이벤트 전파 지연 동안 새 사례가 할당됨

# 올바른 예: 할당 일시 중지 로직을 Distribution 내부로 이동
class DistributionService:
    def pause_assignment(self, agent_id, duration_hours):
        # 직접 내부 상태 업데이트 → 즉시 효과
        self._paused_agents[agent_id] = datetime.now() + timedelta(hours=duration_hours)

    def assign_case(self, case):
        agent = self._find_available_agent(case)
        # _find_available_agent가 일시 중지 상태를 즉시 반영

기법 2 — 계약 결합 도입 (Contract Coupling)

침입 결합이나 모델 결합을 API/계약으로 대체해 경계를 강화.

# 잘못된 예: 외부 서비스 DB에 직접 접근 (침입 결합)
class SupportCaseService:
    def update_knowledge_base(self, case):
        # CMS의 내부 DB 직접 접근
        self.cms_db.execute(
            "INSERT INTO kb_articles (title, content) VALUES (?, ?)",
            (case.title, case.resolution)
        )

# 올바른 예: 공식 API(계약 결합)로만 접근
class SupportCaseService:
    def __init__(self, kb_client: KnowledgeBaseClient):
        self.kb_client = kb_client  # 계약 기반 인터페이스

    def update_knowledge_base(self, case):
        # Knowledge Base의 내부 구조를 모름 — API만 호출
        self.kb_client.submit_article(
            title=case.title,
            content=case.resolution
        )

기법 3 — 단일 소스 추출 (Single Source Extraction)

복제된 로직이 변동성이 높아진 경우, 공통 컴포넌트로 통합.

# 잘못된 예: 중요도 평가 로직이 두 곳에 복제
class DistributionService:
    def evaluate_priority(self, case):
        # 중요도 평가 로직 — 복제본 A
        if case.urgency == "high": return 1
        if case.customer.is_strategic: return 2
        if case.has_recent_escalation: return 3
        return 4

class RealTimeAnalyticsService:
    def evaluate_priority(self, case):
        # 중요도 평가 로직 — 복제본 B (동기화 필요)
        if case.urgency == "high": return 1
        if case.customer.is_strategic: return 2
        if case.has_recent_escalation: return 3
        return 4

# 올바른 예: Support Case Management로 이동 (단일 소스)
class SupportCaseManagementService:
    def evaluate_priority(self, case) -> Priority:
        """중요도 평가 단일 소스. Distribution과 RealTime Analytics 모두 참조."""
        if case.urgency == "high": return Priority.CRITICAL
        if case.customer.is_strategic: return Priority.HIGH
        if case.has_recent_escalation: return Priority.ELEVATED
        return Priority.NORMAL

# Distribution, RealTime Analytics 모두 SupportCaseManagement를 참조

핵심 개념 정리

개념 한 줄 설명
전술적 변경 "어떻게"를 바꿈. 현재 설계가 수용 가능
전략적 변경 "무엇을"을 바꿈. 기존 가정이 깨지고 재조정 필요
결합 균형 공식 (STRENGTH XOR DISTANCE) OR NOT VOLATILITY — 한 차원 변화 시 다른 차원으로 보상
기능적 성장 구성요소 추가 → 상호작용 수 증가 → 전역 복잡성 위험
비즈니스 전략 변화 하위 도메인 유형 전환 → 변동성 변화 → 재조정 필요
조직 변화 팀 분리 → 거리 증가 → 경계 조여야 함
기능 추출·이동 통합 강도 증가 시 기능을 더 가까운 곳으로 이동해 거리 줄임
계약 결합 도입 침입·모델 결합을 API 경계로 격상해 변동성 보상
단일 소스 추출 복제된 로직의 변동성이 높아졌을 때 공통 컴포넌트로 통합
지역 ↔ 전역 복잡성 재조정이 복잡성 총량을 줄이지 못하면 위치만 이동한 것
복제 허용 조건 낮은 변동성이 높은 강도·먼 거리를 균형잡을 때만 복제 유지 허용

실무 체크리스트

  • [ ] 이 변경은 전술적인가, 전략적인가? 기존 설계 가정이 깨지는 변화인가?
  • [ ] 전략적 변경의 빙산 효과를 의심했는가? (무해해 보이는 if 문이 실제 도메인 모델 변화를 숨기고 있지 않은가?)
  • [ ] 통합 강도가 증가했는가? → 거리를 줄일 수 있는가? (기능 추출·이동)
  • [ ] 변동성이 증가했는가? → 강도를 낮출 수 있는가, 거리를 줄일 수 있는가?
  • [ ] 거리가 증가했는가? → 경계를 조이는가? (모델 결합 → 계약 결합)
  • [ ] 하위 도메인 유형이 바뀌지 않았는가? (일반→핵심, 지원→핵심 전환 감지)
  • [ ] 복제된 로직의 변동성이 높아지지 않았는가? → 단일 소스로 통합할 시점
  • [ ] 재조정 후 지역 복잡성과 전역 복잡성 트레이드오프를 검토했는가?
  • [ ] 점진적 재조정인가, 한 번에 모두 바꾸는 Big Bang인가? 후자 경고 신호.
  • [ ] 불균형을 알아차리지 못하거나 대응하지 않으면 기술 부채와 우발적 복잡성으로 이어진다.

연습문제 (문제만 — 정답은 부록 D)

  1. 분류. 다음 변경이 전술적인지 전략적인지 판단하고 이유를 설명하라. (a) 결제 모듈에 카드사 결제 수단 하나 추가 (b) 회사가 자체 물류를 외부 위탁으로 전환하며 물류 하위 도메인이 일반 하위 도메인으로 격하 (c) 성능 개선을 위해 DB 쿼리 최적화.

  2. 분석. 균형 공식 BALANCE = (STRENGTH XOR DISTANCE) OR NOT VOLATILITY에서 통합 강도는 높고(기능 결합), 거리는 멀고(다른 서비스), 변동성도 높다면(핵심 하위 도메인), 이 상태는 균형인가 불균형인가? 어떤 차원을 어떻게 조정해야 하는가?

  3. 진단. WolfDesk 사례에서 Distribution이 Help Desks의 이벤트를 구독해 에이전트 일정을 관리할 때 발생한 경쟁 조건 문제를 결합 균형 공식으로 분석하라. 어느 차원이 어떻게 변했는가?

  4. 설계. 팀이 모놀리스를 마이크로서비스로 분리하면서 두 모듈(OrderService, InventoryService)이 내부 모델을 직접 공유하던 방식을 유지하려 한다. 이것이 왜 문제인가? 어떤 리팩토링 기법으로 해결해야 하는가?

  5. 판단. "복제된 로직은 반드시 제거해야 한다"는 주장은 옳은가? WolfDesk 사례에서 Distribution과 RealTime Analytics의 중요도 평가 로직 복제를 처음에 팀이 그대로 둔 이유를 설명하고, 그것이 언제 잘못된 결정이 됐는지 서술하라.

최신 동향 (2026-05)

최신 동향 (검증 2026-05-21) — 결합 재조정 원리는 그대로 유효. 다만 현대 분산 시스템에서 이를 실천하는 패턴과 도구가 성숙했다.

  • Strangler Fig 패턴 (martinfowler.com) — 모놀리스를 한 번에 분리하지 않고 기능별로 점진적으로 새 서비스로 이전. Big Bang 리팩토링 안티패턴의 현장 검증된 대안. 거리와 강도를 단계별로 재조정하는 접근.
  • Branch by Abstraction (martinfowler.com) — 계약 결합(인터페이스·추상화 계층)을 먼저 도입한 뒤 구현체를 교체하는 기법. 변동성이 높아진 컴포넌트를 안전하게 재조정할 때 사용.
  • Contract Testing (Pact) (docs.pact.io) — 마이크로서비스 간 계약 결합을 자동화된 테스트로 검증. 거리가 증가한 후 경계를 강화할 때 계약 위반을 CI 단계에서 조기 감지.

부록 A. 용어 사전

한글 용어 원문 영문명 의미
결합 재조정 Rebalancing Coupling 결합 균형이 깨졌을 때 세 차원을 조정해 균형 복원
전술적 변경 Tactical Change "어떻게"를 바꿈. 기존 설계 가정 유지
전략적 변경 Strategic Change "무엇을"을 바꿈. 기존 가정이 깨짐
통합 강도 Integration Strength 두 구성요소가 협력하는 긴밀함 (계약→기능→침입 방향)
거리 Distance 구성요소의 물리적·조직적 분리 정도
변동성 Volatility 구성요소가 바뀔 가능성. 핵심 도메인↑, 일반 도메인↓
핵심 하위 도메인 Core Subdomain 경쟁 우위, 높은 변동성
지원 하위 도메인 Supporting Subdomain 필요하지만 경쟁 우위 없음
일반 하위 도메인 Generic Subdomain 범용 솔루션, 낮은 변동성
계약 결합 Contract Coupling 공개 API·명시적 계약을 통한 통합. 경계가 명확
침입 결합 Intrusive Coupling 다른 컴포넌트의 내부(DB 등)에 직접 접근
경쟁 조건 Race Condition 비동기 통합에서 이벤트 전파 지연으로 상태 불일치
지역 복잡성 Local Complexity 단일 컴포넌트 안의 복잡성
전역 복잡성 Global Complexity 컴포넌트 간 상호작용에서 발생하는 복잡성
리프트 앤 시프트 Lift-and-Shift 온프레미스 시스템을 그대로 클라우드로 이전하는 전략

부록 B. 핵심 비교표

전술적 변경 vs 전략적 변경

구분 전술적 전략적
바꾸는 것 "어떻게" (구현 방식) "무엇을" (도메인·목표·구조)
기존 가정 유지 깨짐
설계 수용 여부 현재 설계가 수용 재조정 필요
예시 버그 수정, 새 결제 수단 추가 비즈니스 도메인 전환, 조직 분리

세 차원 변화별 재조정 전략

변화 문제 재조정 기법
통합 강도↑ 긴밀한 협력이 먼 거리와 충돌 기능 추출·이동 (거리 최소화)
변동성↑ 자주 바뀌는 컴포넌트가 강하게 결합 강도 줄이기 (계약 결합 도입) 또는 거리 줄이기
거리↑ 팀 분리로 연쇄 변경 비용 증가 경계 조이기 (모델→계약 결합 격상)

WolfDesk 사례별 재조정 요약

사례 변화 재조정
할당 일시 중지 강도↑ (트랜잭션 수준 기대) + 거리↑ 기능을 Distribution 내부로 이동
중요도 평가 로직 (변동성↑) 지원→핵심 전환, 변동성↑ Support Case Management로 단일화
Knowledge Base (변동성↑) 일반→핵심 전환, 침입 결합 위험 API(계약 결합)로 경계 강화
모놀리스→마이크로서비스 (거리↑) 거리↑, 연쇄 변경 위험 모델→계약 결합으로 경계 조임
중요도 평가 로직 (변동성 낮을 때) 강도↑·거리↑이지만 변동성 낮음 복제 유지 허용 (낮은 변동성이 균형)

부록 C. 추천 참고 자료 & 링크

Tier 1 공식·표준 (생존 확인 2026-05-21)

자료 링크
책 공식 (제이펍) jpub.kr
원서 — Manning Balancing Coupling in Software Design
Strangler Fig 패턴 (Fowler) martinfowler.com
Branch by Abstraction (Fowler) martinfowler.com
Contract Testing - Pact docs.pact.io
마이크로서비스 패턴 카탈로그 microservices.io/patterns
DDD Subdomain 개념 (Eric Evans) domainlanguage.com

책 다른 장 안내

자료 설명
4장 모듈성 — 변화를 수용하는 시스템 설계
7장 통합 강도 — 강도의 6단계 분류
9장 개별 모듈 차원의 변경 다루기 + 하위 도메인
10장 결합 균형 공식 — 세 차원의 균형 찾기
12장 시스템 성장·진화의 본질 — 복잡성 관리의 다음 단계

부록 D. 연습문제 풀이

  1. (a) 전술적 / (b) 전략적 / (c) 전술적
  2. (a) 카드사 결제 수단 추가는 기존 결제 경계·설계 가정을 유지한 채 구현 방식을 확장한다. 전술적 변경.
  3. (b) 물류 하위 도메인이 일반으로 격하되면 변동성이 낮아지고 컴포넌트 간 결합 전략 자체가 바뀐다 — 기존 가정 붕괴. 전략적 변경.
  4. (c) DB 쿼리 최적화는 외부 인터페이스·도메인 가정을 건드리지 않는 구현 개선. 전술적 변경.

  5. (불균형 — 거리를 줄여야 한다) 강도↑ + 거리↑ + 변동성↑는 균형 공식을 만족시키지 못한다. 강도와 거리가 동시에 높으면 XOR 조건 불충족. 변동성도 높아 NOT VOLATILITY 조건도 불충족. 해결: ① 거리를 줄인다 (기능을 더 가까운 컴포넌트로 이동), ② 강도를 줄인다 (계약 결합으로 격상), 또는 두 가지 동시 적용.

  6. (강도↑가 발생했는데 거리는 그대로 — 불균형) 처음: 비동기 이벤트 통합 (낮은 강도) + 다른 서비스 (먼 거리) → 균형. 요구사항 변화: "버튼 클릭 즉시 효과" = 사실상 트랜잭션 결합 수준의 강도↑. 강도가 올라갔는데 거리는 그대로 (비동기 이벤트 방식 유지) → 불균형. 이벤트 전파 지연 동안 새 사례 할당 → 경쟁 조건. 해결: 할당 일시 중지 기능을 Distribution 내부로 이동해 거리 제거.

  7. (거리↑ 시 모델 결합 유지는 위험 — 계약 결합으로 격상해야) 모놀리스 시절엔 거리가 가까워 모델 공유가 쉬웠다. 마이크로서비스로 분리되면 거리↑. 이 상태에서 내부 모델을 계속 공유하면 OrderService가 InventoryService 내부 모델을 바꿀 때마다 서로 깨진다. 해결: 두 서비스 사이에 명시적 계약(API/이벤트 스키마)을 도입 — 계약 결합으로 격상. 공유 지식을 최소화하고 경계를 조인다.

  8. (아니다 — 변동성이 낮을 때 복제는 균형의 한 방법) 처음에 중요도 평가 로직을 복제한 것은 합리적 결정이었다. 로직이 간단하고 변경될 예상이 없었다 (낮은 변동성). 낮은 변동성이 높은 강도·먼 거리를 균형잡았다. 복제를 제거하기 위해 새 컴포넌트를 도입하는 것 자체가 불필요한 복잡성을 추가했을 것이다. 잘못된 결정이 된 시점: WolfDesk 분석 부서가 우선순위 최적화를 핵심 경쟁력으로 격상시키면서 변동성이 높아진 순간. 낮은 변동성이라는 전제가 무너지자 복제 유지 가정도 함께 무너졌다. → 이것이 전략적 변경의 전형: 무해해 보이던 설계 결정의 전제가 바뀐 것.

난이도
에피소드
질문
카드를 로딩 중...
답변

클릭하거나 Space를 눌러 뒤집기

0 / 0
학습 진도 0%
이동   Space 뒤집기   R 셔플